package com.mach.platform.service;

import cn.hutool.setting.Setting;
import com.google.common.base.Splitter;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.io.ByteStreams;
import com.mach.platform.api.domain.Message;
import com.mach.platform.constants.CommonConstants;
import com.mach.platform.domain.EnergyStruc;
import com.mach.platform.domain.PageVo;
import com.mach.platform.domain.iot.*;
import com.mach.platform.repository.EnergyStrucRepo;
import com.mach.platform.repository.IotDevParamsRepo;
import com.mach.platform.repository.IotDevRepo;
import com.mach.platform.repository.IotSpaceRepo;
import com.mach.platform.service.js.iot.IOTJsService;
import com.mach.platform.util.SqlHelper;
import com.mach.platform.utils.CacheUtils;
import com.mach.platform.utils.UUIDUtils;
import com.mach.platform.utils.springdata.Collections3;
import com.mach.platform.utils.springdata.DynamicSpecifications;
import com.mach.platform.utils.springdata.SearchFilter;
import lombok.extern.slf4j.Slf4j;
import org.hibernate.SQLQuery;
import org.hibernate.transform.Transformers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import javax.sql.DataSource;
import javax.transaction.Transactional;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.sql.SQLException;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static com.mach.platform.constants.CommonConstants.*;

/**
 * @author Anonymous
 * @Description: 设备库 服务类
 * @Package: com.mach.platform.service
 * @time 2018/04/27 23:11
 */
@Slf4j
@Service
public class IotSpaceServiceImpl implements BaseService<IotSpace> {

    @Autowired
    private IotSpaceRepo spaceRepo;

    @Autowired
    private IotDevRepo iotDevRepo;

    @Autowired
    private EnergyStrucRepo energyRepo;

    @PersistenceContext
    private EntityManager em;

    @Autowired
    private IotDevParamsRepo devParamsRepo;

    @Autowired
    private IOTJsService jsService;

    @Autowired
    private DataSource dataSource;
    /**
     * 程序增加能源架构
     */
    public void addEnergyStruc() {
        String[] names = {"武汉工厂", "常州工厂"};
        String[] factorys = {"WH", "CZ"};
        String[] workShops = {"冲压车间", "焊装车间", "涂装车间", "总装车间", "树脂车间", "综合动力"};
        String[] enerys = {"冷量", "总览", "电", "水", "中水", "蒸汽", "燃气", "模板", "碳排", "成本", "压缩空气"};
        long[] factoryEnerysIds = {796, 804, 1, 799, 797, 798, 800, 1, 801, 802, 803}; // 工厂能源架构对应的id
        // 插入工厂能源架构
//		for (int i = 0; i < names.length; i++) {
//			for (int j = 0; j < enerys.length; j++) {
//				EnergyStruc energyStruc = new EnergyStruc();
//				energyStruc.setFactory(factorys[i]);
//				energyStruc.setLevel(1);
//				energyStruc.setName(names[i]);
//				energyStruc.setPid(factoryEnerysIds[j]);
//				energyStruc.setSort(i);
//				energyStruc.setType(enerys[j]);
//				energyRepo.save(energyStruc);
//			}
//		}

        // 插入车间能源架构
        for (int i = 0; i < workShops.length; i++) {
            for (int j = 0; j < factorys.length; j++) {
                for (String enery : enerys) {
                    EnergyStruc aaa = energyRepo.findAllByNameAndType(names[j], enery).get(0);
                    EnergyStruc energyStruc = new EnergyStruc();
                    energyStruc.setFactory(factorys[j]);
                    energyStruc.setLevel(2);
                    energyStruc.setName(workShops[i]);
                    energyStruc.setPid(aaa.getId());
                    energyStruc.setSort(i);
                    energyStruc.setType(enery);
                    energyRepo.save(energyStruc);
                }
            }
        }

    }

    /**
     * 查询母排有关的空间数据(车间和母线)
     *
     * @param type 查询类型 1.车间 2.母线
     * @param id   空间id
     * @return
     */
    public List<Map> busbarSpaces(int type, Long id) {
        if (type == 1) { // 查询母排下面的所有车间
            return spaceRepo.findBusbarWorkShop(id);
        }
        List<Map> mapList = spaceRepo.findByParentId(id);
        List<Map> result = new ArrayList<>();
        Map space;
        for (Map map : mapList) {
            space = new HashMap();
            space.put("value", map.get("id"));
            space.put("label", map.get("name"));
            result.add(space);
        }
        return result;
    }

    /**
     * 删除空间，设备，参数(临时删除一些空间，设备数据，用于测试)
     *
     * @param ids
     */
    @Transactional(rollbackOn = Exception.class)
    public boolean deleteSpaceDev(Long[] ids) {
        // 初始化数据
        List<Long> spaceIds = Arrays.asList(ids);
        // 删除空间
        for (int i = 0; i < ids.length; i++) {
            Long Item = ids[i];
            // 获取 该节点下的子级空间id--- 包含自己
            String sql = "select countupSpaceSubsets (" + Item + ")";
            String singleResult = em.createNativeQuery(sql).getSingleResult().toString();
            List<Long> sonIds = Splitter.on(",").splitToList(singleResult).stream().filter(str -> !str.equals("")).map(si -> Long.parseLong(si)).collect(Collectors.toList());
            // 合并去重 空间id
            spaceIds = Stream.concat(spaceIds.stream(), sonIds.stream()).distinct().map(son -> Long.parseLong(son.toString())).collect(Collectors.toList());
        }
        spaceRepo.deleteByIdIn(spaceIds.stream().toArray(Long[]::new));
        // 删除设备
        List devIds = iotDevRepo.findBySpaceIdIn(spaceIds);
//		iotDevRepo.deleteByIdIn(devIds.stream().toArray(Long[]::new));
        devIds.forEach(id -> {
            Long longId = new BigInteger(id.toString()).longValue();
            iotDevRepo.deleteById(longId);
        });
        // 删除设备参数
        devParamsRepo.deleteByDevIds(devIds);
        return true;
    }


    /**
     * 查询空间下面的分页设备数据
     *
     * @param pageable 分页参数
     * @param id       空间id
     * @return
     */
    public PageVo pageIotDevBySpaceId(Pageable pageable, Long id) {
        Page<Map> iotDevPage = iotDevRepo.pageIotDevBySpaceId(id, pageable);
        List<Map> mapList = new ArrayList<>();
        Map newIotDev;
        for (Map iotDev : iotDevPage.getContent()) {
            newIotDev = new HashMap();
            newIotDev.put("id", iotDev.get("id"));
            newIotDev.put("name", iotDev.get("name"));
            newIotDev.put("status", 2);
            List<Map> itemList = new ArrayList<>();
            Map item;
            for (int i = 0; i < 4; i++) {
                item = new HashMap();
                item.put("value", "");
                item.put("status", 1);
                itemList.add(item);
            }
            newIotDev.put("itemData", itemList);
            mapList.add(newIotDev);
        }
        PageVo pageVo = new PageVo();
        pageVo.setPage(pageable.getPageNumber());
        pageVo.setSize(pageable.getPageSize());
        pageVo.setTotalElements(iotDevPage.getTotalElements());
        pageVo.setTotalPages(iotDevPage.getTotalPages());
        pageVo.setContent(mapList);
        return pageVo;
    }


    /**
     * 保存
     *
     * @param space 保存的实体
     * @return T 返回保存后的实体
     */
    @Transactional(rollbackOn = Exception.class)
    @Override
    public IotSpace save(IotSpace space) {

        IotSpace dbResult = spaceRepo.saveAndFlush(space);
        String queryParent = queryParent(dbResult.getId());
        if (queryParent != null) {
            CacheUtils.guavaCacheFactory.put(SPACE_LEVEL_PREFIX + dbResult.getId(), queryParent);
        }
        return dbResult;
    }

    /**
     * 创建一个制冷系统~~
     *
     * @param space
     * @param config
     * @return
     */
    @Transactional(rollbackOn = Exception.class)
    public IotSpace createCoolSystem(IotSpace space, Map<String, Integer> config) {

        // 顶级节点
        space.setType(51);
        IotSpace topSpace = save(space);

        // 递归生成子节点
        this.coldRecursionForGenerateSubSpaces(topSpace, config);

        // 手動重啓js引擎, 延时3s执行
        new Timer().schedule(new TimerTask() {
            @Override
            public void run() {
                jsService.flushAndReload();
            }
        },3500);

        return topSpace;
    }


    /**
     * 递归生成 制冷站的树目录数据结构
     * @param iotSpace 制冷站顶级空间实例
     * @param param 生成的一些参数
     */
    public void coldRecursionForGenerateSubSpaces(IotSpace iotSpace, Map param) {
        Integer type = iotSpace.getType();
        switch (type) {
            case 51:
                String[] texts = new String[]{"工艺监视", "工艺控制", "工艺能效"};
                for (int i = 0; i < texts.length; i++) {
                    IotSpace cur = new IotSpace();
                    cur.setParentId(iotSpace.getId());
                    cur.setName(texts[i]);
                    cur.setType(100 + i);
                    cur.setSort(1 + i);
                    IotSpace newSpace = spaceRepo.saveAndFlush(cur);
                    coldRecursionForGenerateSubSpaces(newSpace,param);
                }
                break;
            case 100:
                String[] text100 = new String[]{"制冷机房", "供冷计量", "总装车间"};
                for (int i = 0; i < text100.length; i++) {
                    IotSpace cur2 = new IotSpace();
                    cur2.setParentId(iotSpace.getId());
                    cur2.setName(text100[i]);
                    cur2.setType(200 + i);
                    cur2.setSort(1 + i);
                    IotSpace newSpace = spaceRepo.saveAndFlush(cur2);
                    coldRecursionForGenerateSubSpaces(newSpace, param);
                }
                break;
            case 101:
                String[] text101 = new String[]{"制冷机房", "一级管网", "总装管网"};
                for (int i = 0; i < text101.length; i++) {
                    IotSpace cur2 = new IotSpace();
                    cur2.setParentId(iotSpace.getId());
                    cur2.setName(text101[i]);
                    cur2.setType(500 + i);
                    cur2.setSort(1 + i);
                    IotSpace newSpace = spaceRepo.saveAndFlush(cur2);
                    coldRecursionForGenerateSubSpaces(newSpace, param);
                }
                break;
            case 102:
                String[] text102 = new String[]{"总量栏", "一区左","一区右", "二区左","二区右"};
                for (int i = 0; i < text102.length; i++) {
                    IotSpace cur3 = new IotSpace();
                    cur3.setParentId(iotSpace.getId());
                    cur3.setName(text102[i]);
                    cur3.setSort(1 + i);
                    IotSpace newSpace = spaceRepo.saveAndFlush(cur3);
                    cur3.setType(400 + i);
                    if (i == 0) {
                        autoGenerateCoolSysVirtualDevices(newSpace, "制冷站房");
                    }
                    if (i == 1 || i == 2) {
                        // 总冷量柱状图
                        autoGenerateCoolSysVirtualDevicesZone(newSpace, "制冷站房", 1);
                    }
                    if (i == 3 || i == 4) {
                        // 总冷量柱状图
                        autoGenerateCoolSysVirtualDevicesZone(newSpace, "制冷站房", 2);
                    }
                    coldRecursionForGenerateSubSpaces(newSpace, param);
                }
                break;
            case 9:
                if (iotSpace.getName().equals("制冷机房")) {
                    String[] others = new String[]{"冷冻泵", "制冷主机", "冷却泵", "冷却塔", "用能车间"};
                    for (int i = 0; i < others.length; i++) {
                        IotSpace cur2 = new IotSpace();
                        cur2.setParentId(iotSpace.getId());
                        cur2.setName(others[i]);
                        cur2.setType(6);
                        cur2.setSort(1 + i);
                        IotSpace newSpace = spaceRepo.saveAndFlush(cur2);
                        coldRecursionForGenerateSubSpaces(newSpace, param);
                    }
                }
                break;
            case 500:
                String[] others2 = new String[]{"冷冻泵", "制冷主机", "冷却泵", "冷却塔", "用能车间"};
                for (int i = 0; i < others2.length; i++) {
                    IotSpace cur2 = new IotSpace();
                    cur2.setParentId(iotSpace.getId());
                    cur2.setName(others2[i]);
                    cur2.setType(6);
                    cur2.setSort(1 + i);
                    IotSpace newSpace = spaceRepo.saveAndFlush(cur2);
                    coldRecursionForGenerateSubSpaces(newSpace,param);
                }
                break;
            case 6:
                String[] others = new String[]{"控制设备", "机组设备"};
                for (int i = 0; i < others.length; i++) {
                    IotSpace cur2 = new IotSpace();
                    cur2.setParentId(iotSpace.getId());
                    cur2.setName(others[i]);
                    cur2.setType(10 + i);
                    cur2.setSort(1 + i);
                    IotSpace newSpace = spaceRepo.saveAndFlush(cur2);
                    // 生成设备
                    createModelVirtualIotDev(newSpace, i, iotSpace,param);
                    coldRecursionForGenerateSubSpaces(newSpace, param);
                }
                break;

            case 200:
                String[] texts3 = new String[]{"监视系统一", "监视系统二", "参数一区", "参数二区", "参数三区", "参数四区", "参数五区", "参数六区"};
                for (int i = 0; i < texts3.length; i++) {
                    IotSpace cur = new IotSpace();
                    cur.setParentId(iotSpace.getId());
                    cur.setName(texts3[i]);
                    cur.setType(300 + i);
                    cur.setSort(1 + i);
                    IotSpace newSpace = spaceRepo.saveAndFlush(cur);
                    if (i == 0) {
                        autoGenerateCoolSysVirtualDevice(newSpace, "制冷站房", null);
                    }
                    coldRecursionForGenerateSubSpaces(newSpace, param);
                }
                break;
            case 201:
                String[] texts4 = new String[]{"冲压车间", "涂装车间", "树脂车间", "机加车间", "焊装车间", "铸造车间", "总装车间"};
                for (int i = 0; i < texts4.length; i++) {
                    IotSpace cur = new IotSpace();
                    cur.setParentId(iotSpace.getId());
                    cur.setName(texts4[i]);
                    cur.setType(3);
                    cur.setSort(1 + i);
                    IotSpace newSpace = spaceRepo.saveAndFlush(cur);
                    coldRecursionForGenerateSubSpaces(newSpace, param);
                }
                break;
            case 202:
                String[] texts5 = new String[]{"1#风柜", "2#风柜", "3#风柜", "4#风柜", "5#风柜", "6#风柜", "7#风柜", "8#风柜", "9#风柜", "10#风柜"};
                for (int i = 0; i < texts5.length; i++) {
                    IotSpace cur = new IotSpace();
                    cur.setParentId(iotSpace.getId());
                    cur.setName(texts5[i]);
                    cur.setType(4);
                    cur.setSort(1 + i);
                    IotSpace newSpace = spaceRepo.saveAndFlush(cur);
                    coldRecursionForGenerateSubSpaces(newSpace, param);
                }
                break;
            default:
                break;
        }
    }


    @Transactional(rollbackOn = Exception.class)
    public IotSpace save2(IotSpace space, Integer ifBornSons) {
        IotSpace dbResult = save(space);
        if (ifBornSons != null) {
            String[] texts1 = new String[]{"工艺监视", "工艺控制", "工艺能效"};
            String[] texts2 = new String[]{"控制设备", "机组设备"};
            String[] texts3 = new String[]{"监视系统一", "监视系统二", "参数一区", "参数二区", "参数三区", "参数四区", "参数五区", "参数六区"};
            String[] texts4 = new String[]{"冲压车间", "涂装车间", "树脂车间", "机加车间", "焊装车间", "铸造车间", "总装车间"};
            List<IotSpace> saveLists = Lists.newArrayList();
            switch (ifBornSons) {
                case 1:
                    recursionForSpace(dbResult);
                    break;
                case 2:
                    for (int i = 0; i < texts2.length; i++) {
                        IotSpace cur = new IotSpace();
                        cur.setParentId(dbResult.getId());
                        cur.setName(texts2[i]);
                        cur.setSort(1 + i);
                        cur.setType(10 + i);
                        saveLists.add(cur);
                    }
                    break;
                case 3:
                    for (int i = 0; i < texts3.length; i++) {
                        IotSpace cur = new IotSpace();
                        cur.setParentId(dbResult.getId());
                        cur.setName(texts3[i]);
                        cur.setType(300 + i);
                        cur.setSort(1 + i);
                        saveLists.add(cur);
                    }
                    break;
                case 4:
                    for (int i = 0; i < texts4.length; i++) {
                        IotSpace cur = new IotSpace();
                        cur.setParentId(dbResult.getId());
                        cur.setName(texts4[i]);
                        cur.setType(3);
                        cur.setSort(1 + i);
                        saveLists.add(cur);
                    }
                    break;
                case 5:
                    recursionForSpace(dbResult);
                    break;

                default:
                    break;
            }

            spaceRepo.saveAll(saveLists);
        }
        return dbResult;
    }


    /**
     * 自动生成空压，制冷，供水，供电，燃气，蒸汽系统旗下节点数据
     *
     * @param iotSpace
     */
    public void recursionForSpace(IotSpace iotSpace) {
        Integer type = iotSpace.getType();
        switch (type) {
            case 50:
                airRecursionForSpace(iotSpace);
                break;
            case 51:
                coldRecursionForSpace(iotSpace);
                break;
            default:
                break;
        }
        // 将站房和用户关联，标记站房是哪个用户创建的

    }


    /**
     * 自动生成空压系统旗下节点数据
     *
     * @param iotSpace
     */
    public void airRecursionForSpace(IotSpace iotSpace) {
        Integer type = iotSpace.getType();
        switch (type) {
            case 50:
                String[] texts = new String[]{"工艺监视", "工艺控制", "工艺能效"};
                for (int i = 0; i < texts.length; i++) {
                    IotSpace cur = new IotSpace();
                    cur.setParentId(iotSpace.getId());
                    cur.setName(texts[i]);
                    cur.setType(100 + i);
                    cur.setSort(1 + i);
                    IotSpace newSpace = spaceRepo.saveAndFlush(cur);
                    airRecursionForSpace(newSpace);
                }
                break;
            case 100:
                String[] text100 = new String[]{"空压机房", "供气计量", "总装车间"};
                for (int i = 0; i < text100.length; i++) {
                    IotSpace cur2 = new IotSpace();
                    cur2.setParentId(iotSpace.getId());
                    cur2.setName(text100[i]);
                    cur2.setType(200 + i);
                    cur2.setSort(1 + i);
                    IotSpace newSpace = spaceRepo.saveAndFlush(cur2);
                    airRecursionForSpace(newSpace);
                }
                break;
            case 101:
                String[] text101 = new String[]{"空压机房", "一级管网", "总装管网"};
                for (int i = 0; i < text101.length; i++) {
                    IotSpace cur2 = new IotSpace();
                    cur2.setParentId(iotSpace.getId());
                    cur2.setName(text101[i]);
                    cur2.setType(500 + i);
                    cur2.setSort(1 + i);
                    IotSpace newSpace = spaceRepo.saveAndFlush(cur2);
                    airRecursionForSpace(newSpace);
                }
                break;
            case 102:
                String[] text102 = new String[]{"总量栏", "一区", "二区"};
                for (int i = 0; i < text102.length; i++) {
                    IotSpace cur3 = new IotSpace();
                    cur3.setParentId(iotSpace.getId());
                    cur3.setName(text102[i]);
                    cur3.setSort(1 + i);
                    IotSpace newSpace = spaceRepo.saveAndFlush(cur3);
                    cur3.setType(400 + i);
                    if (i == 0) {
                        autoGenerateCoolSysVirtualDevices(newSpace, "空压站房");
                    }
                    if (i == 1) {
                        // 总冷量柱状图
                        autoGenerateCoolSysVirtualDevicesZone(newSpace, "空压站房", 1);
                    }
                    if (i == 2) {
                        // 总冷量柱状图
                        autoGenerateCoolSysVirtualDevicesZone(newSpace, "空压站房", 2);
                    }
                    airRecursionForSpace(newSpace);
                }
                break;
            case 9:
                if (iotSpace.getName().equals("空压机房")) {
                    String[] others = new String[]{"分管", "空压机", "冷却泵", "干燥机", "冷却塔", "储气罐"};
                    for (int i = 0; i < others.length; i++) {
                        IotSpace cur2 = new IotSpace();
                        cur2.setParentId(iotSpace.getId());
                        cur2.setName(others[i]);
                        cur2.setType(600 + i);
                        cur2.setSort(1 + i);
                        IotSpace newSpace = spaceRepo.saveAndFlush(cur2);
                        airRecursionForSpace(newSpace);
                    }
                }
                break;
            case 6:
                String[] others = new String[]{"控制设备", "机组设备"};
                for (int i = 0; i < others.length; i++) {
                    IotSpace cur2 = new IotSpace();
                    cur2.setParentId(iotSpace.getId());
                    cur2.setName(others[i]);
                    cur2.setType(10 + i);
                    cur2.setSort(1 + i);
                    IotSpace newSpace = spaceRepo.saveAndFlush(cur2);
                    if (i == 1) {
                        if (iotSpace.getName().equals("储气罐")) {
                            autoGenerateCoolSysVirtualDevice(newSpace, "1#储气罐", null);
                        }
                    }
                    airRecursionForSpace(newSpace);
                }
                break;

            case 200:
                String[] texts3 = new String[]{"监视系统一", "监视系统二", "参数一区", "参数二区", "参数三区", "参数四区", "参数五区", "参数六区"};
                for (int i = 0; i < texts3.length; i++) {
                    IotSpace cur = new IotSpace();
                    cur.setParentId(iotSpace.getId());
                    cur.setName(texts3[i]);
                    cur.setType(300 + i);
                    cur.setSort(1 + i);
                    IotSpace newSpace = spaceRepo.saveAndFlush(cur);
                    if (i == 0) {
                        autoGenerateCoolSysVirtualDevice(newSpace, "空压站房", "gas");
                    }
                    if (i == 1) {
                        autoGenerateCoolSysVirtualDevice(newSpace, "空压站房", "cold");
                    }
                    airRecursionForSpace(newSpace);
                }
                break;
            case 201:
                String[] texts4 = new String[]{"冲压车间", "涂装车间", "树脂车间", "机加车间", "焊装车间", "铸造车间", "总装车间"};
                for (int i = 0; i < texts4.length; i++) {
                    IotSpace cur = new IotSpace();
                    cur.setParentId(iotSpace.getId());
                    cur.setName(texts4[i]);
                    cur.setType(3);
                    cur.setSort(1 + i);
                    IotSpace newSpace = spaceRepo.saveAndFlush(cur);
                    airRecursionForSpace(newSpace);
                }
                break;
            case 202:
                String[] texts5 = new String[]{"1#风柜", "2#风柜", "3#风柜", "4#风柜", "5#风柜", "6#风柜", "7#风柜", "8#风柜", "9#风柜", "10#风柜"};
                for (int i = 0; i < texts5.length; i++) {
                    IotSpace cur = new IotSpace();
                    cur.setParentId(iotSpace.getId());
                    cur.setName(texts5[i]);
                    cur.setType(4);
                    cur.setSort(1 + i);
                    IotSpace newSpace = spaceRepo.saveAndFlush(cur);
                    airRecursionForSpace(newSpace);
                }
                break;
            default:
                break;
        }
    }


    /**
     * 自动生成制冷系统旗下节点数据
     *
     * @param iotSpace
     */
    public void coldRecursionForSpace(IotSpace iotSpace) {
        Integer type = iotSpace.getType();
        switch (type) {
            case 51:
                String[] texts = new String[]{"工艺监视", "工艺控制", "工艺能效"};
                for (int i = 0; i < texts.length; i++) {
                    IotSpace cur = new IotSpace();
                    cur.setParentId(iotSpace.getId());
                    cur.setName(texts[i]);
                    cur.setType(100 + i);
                    cur.setSort(1 + i);
                    IotSpace newSpace = spaceRepo.saveAndFlush(cur);
                    coldRecursionForSpace(newSpace);
                }
                break;
            case 100:
                String[] text100 = new String[]{"制冷机房", "供冷计量", "总装车间"};
                for (int i = 0; i < text100.length; i++) {
                    IotSpace cur2 = new IotSpace();
                    cur2.setParentId(iotSpace.getId());
                    cur2.setName(text100[i]);
                    cur2.setType(200 + i);
                    cur2.setSort(1 + i);
                    IotSpace newSpace = spaceRepo.saveAndFlush(cur2);
                    coldRecursionForSpace(newSpace);
                }
                break;
            case 101:
                String[] text101 = new String[]{"制冷机房", "一级管网", "总装管网"};
                for (int i = 0; i < text101.length; i++) {
                    IotSpace cur2 = new IotSpace();
                    cur2.setParentId(iotSpace.getId());
                    cur2.setName(text101[i]);
                    cur2.setType(500 + i);
                    cur2.setSort(1 + i);
                    IotSpace newSpace = spaceRepo.saveAndFlush(cur2);
                    coldRecursionForSpace(newSpace);
                }
                break;
            case 102:
                String[] text102 = new String[]{"总量栏", "一区左","一区右", "二区左","二区右"};
                for (int i = 0; i < text102.length; i++) {
                    IotSpace cur3 = new IotSpace();
                    cur3.setParentId(iotSpace.getId());
                    cur3.setName(text102[i]);
                    cur3.setSort(1 + i);
                    IotSpace newSpace = spaceRepo.saveAndFlush(cur3);
                    cur3.setType(400 + i);
                    if (i == 0) {
                        autoGenerateCoolSysVirtualDevices(newSpace, "制冷站房");
                    }
                    if (i == 1 || i==2) {
                        // 总冷量柱状图
                        autoGenerateCoolSysVirtualDevicesZone(newSpace, "制冷站房", 1);
                    }
                    if (i == 3 || i == 4) {
                        // 总冷量柱状图
                        autoGenerateCoolSysVirtualDevicesZone(newSpace, "制冷站房", 2);
                    }
                    coldRecursionForSpace(newSpace);
                }
                break;
            case 9:
                if (iotSpace.getName().equals("制冷机房")) {
                    String[] others = new String[]{"冷冻泵", "制冷主机", "冷却泵", "冷却塔", "用能车间"};
                    for (int i = 0; i < others.length; i++) {
                        IotSpace cur2 = new IotSpace();
                        cur2.setParentId(iotSpace.getId());
                        cur2.setName(others[i]);
                        cur2.setType(6);
                        cur2.setSort(1 + i);
                        IotSpace newSpace = spaceRepo.saveAndFlush(cur2);
                        coldRecursionForSpace(newSpace);
                    }
                }
                break;
            case 500:
                String[] others2 = new String[]{"冷冻泵", "制冷主机", "冷却泵", "冷却塔", "用能车间"};
                for (int i = 0; i < others2.length; i++) {
                    IotSpace cur2 = new IotSpace();
                    cur2.setParentId(iotSpace.getId());
                    cur2.setName(others2[i]);
                    cur2.setType(6);
                    cur2.setSort(1 + i);
                    IotSpace newSpace = spaceRepo.saveAndFlush(cur2);
                    coldRecursionForSpace(newSpace);
                }
                break;
            case 6:
                String[] others = new String[]{"控制设备", "机组设备"};
                for (int i = 0; i < others.length; i++) {
                    IotSpace cur2 = new IotSpace();
                    cur2.setParentId(iotSpace.getId());
                    cur2.setName(others[i]);
                    cur2.setType(10 + i);
                    cur2.setSort(1 + i);
                    IotSpace newSpace = spaceRepo.saveAndFlush(cur2);
                    // 生成设备
                    generateModelVirtualIotDev(newSpace);
                    // 递归
                    coldRecursionForSpace(newSpace);
                }
                break;

            case 200:
                String[] texts3 = new String[]{"监视系统一", "监视系统二", "参数一区", "参数二区", "参数三区", "参数四区", "参数五区", "参数六区"};
                for (int i = 0; i < texts3.length; i++) {
                    IotSpace cur = new IotSpace();
                    cur.setParentId(iotSpace.getId());
                    cur.setName(texts3[i]);
                    cur.setType(300 + i);
                    cur.setSort(1 + i);
                    IotSpace newSpace = spaceRepo.saveAndFlush(cur);
                    if (i == 0) {
                        autoGenerateCoolSysVirtualDevice(newSpace, "制冷站房", null);
                    }
                    coldRecursionForSpace(newSpace);
                }
                break;
            case 201:
                String[] texts4 = new String[]{"冲压车间", "涂装车间", "树脂车间", "机加车间", "焊装车间", "铸造车间", "总装车间"};
                for (int i = 0; i < texts4.length; i++) {
                    IotSpace cur = new IotSpace();
                    cur.setParentId(iotSpace.getId());
                    cur.setName(texts4[i]);
                    cur.setType(3);
                    cur.setSort(1 + i);
                    IotSpace newSpace = spaceRepo.saveAndFlush(cur);
                    coldRecursionForSpace(newSpace);
                }
                break;
            case 202:
                String[] texts5 = new String[]{"1#风柜", "2#风柜", "3#风柜", "4#风柜", "5#风柜", "6#风柜", "7#风柜", "8#风柜", "9#风柜", "10#风柜"};
                for (int i = 0; i < texts5.length; i++) {
                    IotSpace cur = new IotSpace();
                    cur.setParentId(iotSpace.getId());
                    cur.setName(texts5[i]);
                    cur.setType(4);
                    cur.setSort(1 + i);
                    IotSpace newSpace = spaceRepo.saveAndFlush(cur);
                    coldRecursionForSpace(newSpace);
                }
                break;
            default:
                break;
        }
    }



    public void createModelVirtualIotDev(IotSpace iotSpace, int index, IotSpace fatherSpace,Map params) {

        if (index == 0 && !fatherSpace.getName().equals("用能车间")) {
            // 控制设备 数量1个
            IotDev virDev = new IotDev();
            virDev.setSn(UUIDUtils.generateRandomLetter() + UUIDUtils.generateUUID());  //编号
            virDev.setType(2);
            virDev.setScriptSwitch(1);
            IotDevType devType = new IotDevType();
            devType.setId(1L);
            virDev.setIotDevType(devType);
            virDev.setIotSpace(iotSpace);
            virDev.setScript("");
            virDev.setPic("1999");
            virDev.setName("控制设备");
            // 生成参数
            virDev.setDevParams(generateParams(fatherSpace.getName()));
            // 生成属性
            virDev.setVirtualItems(generateControllDevVirtualItems(fatherSpace.getName()));

            iotDevRepo.saveAndFlush(virDev);

            return;
        }

        if (index == 1) {
            // 生成机组设备
            switch (fatherSpace.getName()) {
                case "冷却泵":
                    // 冷却泵
                    for (int i = 0; i < Integer.parseInt(params.get(SPACE_COOLPUMP_NAME).toString()); i++) {
                        IotDev virDev = new IotDev();
                        virDev.setSn(UUIDUtils.generateRandomLetter() + UUIDUtils.generateUUID());  //编号
                        virDev.setType(2);
                        virDev.setScriptSwitch(1);
                        IotDevType devType = new IotDevType();
                        devType.setId(1L);
                        virDev.setIotDevType(devType);
                        virDev.setIotSpace(iotSpace);
                        virDev.setPic("1005");
                        virDev.setScript("");
                        virDev.setSort(0.1F*(i+1));
                        virDev.setName((i+1)+ "#"+ fatherSpace.getName());
                        // 添加一些属性
                        virDev.setVirtualItems(generateVirtualItems(fatherSpace.getName()));

                        iotDevRepo.saveAndFlush(virDev);
                    }
                    break;
                case "冷冻泵":
                    // 冷冻泵
                    for (int i = 0; i < Integer.parseInt(params.get(SPACE_COLDPUMP_NAME).toString()); i++) {
                        IotDev virDev = new IotDev();
                        virDev.setSn(UUIDUtils.generateRandomLetter() + UUIDUtils.generateUUID());  //编号
                        virDev.setType(2);
                        virDev.setScriptSwitch(1);
                        IotDevType devType = new IotDevType();
                        devType.setId(1L);
                        virDev.setIotDevType(devType);
                        virDev.setIotSpace(iotSpace);
                        virDev.setPic("1006");
                        virDev.setScript("");
                        virDev.setSort(0.1F*(i+1));
                        virDev.setName((i+1) + "#"+ fatherSpace.getName());
                        // 添加一些属性
                        virDev.setVirtualItems(generateVirtualItems(fatherSpace.getName()));
                        iotDevRepo.saveAndFlush(virDev);
                    }
                    break;
                case "冷却塔":
                    // 冷却塔
                    for (int i = 0; i < Integer.parseInt(params.get(SPACE_COOLTOWER_NAME).toString()); i++) {
                        IotDev virDev = new IotDev();
                        virDev.setSn(UUIDUtils.generateRandomLetter() + UUIDUtils.generateUUID());  //编号
                        virDev.setType(2);
                        virDev.setScriptSwitch(1);
                        IotDevType devType = new IotDevType();
                        devType.setId(1L);
                        virDev.setIotDevType(devType);
                        virDev.setIotSpace(iotSpace);
                        virDev.setPic("1004");
                        virDev.setScript("");
                        virDev.setSort(0.1F*(i+1));
                        virDev.setName((i+1) + "#"+ fatherSpace.getName());
                        // 添加一些属性
                        virDev.setVirtualItems(generateVirtualItems(fatherSpace.getName()));
                        iotDevRepo.saveAndFlush(virDev);
                    }
                    break;
                case "制冷主机":
                    // 制冷主机
                    for (int i = 0; i < Integer.parseInt(params.get(SPACE_COOLMAIN_NAME).toString()); i++) {
                        IotDev virDev = new IotDev();
                        virDev.setSn(UUIDUtils.generateRandomLetter() + UUIDUtils.generateUUID());  //编号
                        virDev.setType(2);
                        virDev.setScriptSwitch(1);
                        IotDevType devType = new IotDevType();
                        devType.setId(1L);
                        virDev.setIotDevType(devType);
                        virDev.setIotSpace(iotSpace);
                        virDev.setPic("1009");
                        virDev.setSort(0.1F*(i+1));
                        virDev.setScript("");
                        virDev.setName((i+1) + "#"+ fatherSpace.getName());
                        // 添加一些属性
                        virDev.setVirtualItems(generateVirtualItems(fatherSpace.getName()));
                        iotDevRepo.saveAndFlush(virDev);
                    }
                    break;

                default:
                    // 用能车间
                    IotDev virDev = new IotDev();
                    virDev.setSn(UUIDUtils.generateRandomLetter() + UUIDUtils.generateUUID());  //编号
                    virDev.setType(2);
                    virDev.setScriptSwitch(1);
                    IotDevType devType = new IotDevType();
                    devType.setId(1L);
                    virDev.setIotDevType(devType);
                    virDev.setIotSpace(iotSpace);
                    virDev.setScript("");
                    virDev.setPic("1999");
                    virDev.setSort(0.1F);
                    virDev.setName("用能车间");
                    iotDevRepo.saveAndFlush(virDev);
                    break;
            }
        }
    }

    /**
     * 生成 机组设备的 属性
     * @param type
     * @return
     */
    public List generateVirtualItems(String type) {

        List<IotVirtualItem> iotVirtualItemList = Lists.newArrayList();
        Setting setting = new Setting("station.setting");
        String keyName = "";
        switch (type) {
            case "冷却泵":
                // 冷却泵
                keyName = SPACE_COOLPUMP_NAME;
                break;
            case "冷冻泵":
                // 冷冻泵
                keyName = SPACE_COLDPUMP_NAME;
                break;
            case "冷却塔":
                // 冷却塔
                keyName = SPACE_COOLTOWER_NAME;
                break;
            case "制冷主机":
                // 制冷主机
                keyName = SPACE_COOLMAIN_NAME;
                break;

            default:
                // 用能车间
                break;
        }
        String group = setting.getByGroup(keyName, "refrigeratingStation");
        List<String> props = Splitter.on(",").splitToList(group);
        for (int i = 0; i < props.size(); i++) {
            IotVirtualItem item = new IotVirtualItem();
            item.setName(props.get(i).trim());
            item.setAlias(props.get(i).trim());
            item.setSort(i);
            item.setIsGet(1);
            item.setIsLog(1);
            item.setPropertyType(100);
            iotVirtualItemList.add(item);
        }
        return iotVirtualItemList;
    }

    /**
     * 生成 控制设备的 属性
     * @param type
     * @return
     */
    public List generateControllDevVirtualItems(String type) {

        List<IotVirtualItem> iotVirtualItemList = Lists.newArrayList();
        Setting setting = new Setting("station.setting");
        String keyName = "ctrl_";
        switch (type) {
            case "冷却泵":
                // 冷却泵
                keyName = keyName + SPACE_COOLPUMP_NAME;
                break;
            case "冷冻泵":
                // 冷冻泵
                keyName = keyName + SPACE_COLDPUMP_NAME;
                break;
            case "冷却塔":
                // 冷却塔
                keyName = keyName + SPACE_COOLTOWER_NAME;
                break;
            case "制冷主机":
                // 制冷主机
                keyName = keyName + SPACE_COOLMAIN_NAME;
                break;

            default:
                // 用能车间
                break;
        }
        String group = setting.getByGroup(keyName, "refrigeratingStation");
        List<String> props = Splitter.on(",").splitToList(group);
        for (int i = 0; i < props.size(); i++) {
            IotVirtualItem item = new IotVirtualItem();
            item.setName(props.get(i).trim());
            item.setAlias(props.get(i).trim());
            item.setSort(i);
            item.setIsGet(1);
            item.setPropertyType(100);
            item.setIsLog(1);
            iotVirtualItemList.add(item);
        }
        return iotVirtualItemList;
    }


    /**
     * 生成参数
     * @param type
     * @return
     */
    public List generateParams(String type) {

        List<IotDevParams> iotVirtualItemList = Lists.newArrayList();
        Setting setting = new Setting("station.setting");
        String keyName = "params_";
        switch (type) {
            case "冷却泵":
                // 冷却泵
                keyName = keyName+SPACE_COOLPUMP_NAME;
                break;
            case "冷冻泵":
                // 冷冻泵
                keyName = keyName+SPACE_COLDPUMP_NAME;
                break;
            case "冷却塔":
                // 冷却塔
                keyName = keyName+SPACE_COOLTOWER_NAME;
                break;
            case "制冷主机":
                // 制冷主机
                keyName = keyName+SPACE_COOLMAIN_NAME;
                break;

            default:
                // 用能车间
                break;
        }
        String group = setting.getByGroup(keyName, "refrigeratingStation");
        List<String> props = Splitter.on(";").splitToList(group);
        for (int i = 0; i < props.size(); i++) {
            String prop = props.get(i).trim();
            List<String> propsList = Splitter.on("-").splitToList(prop);
            IotDevParams item = new IotDevParams();
            if (propsList.size() > 0) {
               item.setLabel(propsList.get(0).trim());
            }
            if (propsList.size() > 1) {
               item.setName(propsList.get(1).trim());
            }
            if (propsList.size() > 2) {
               item.setValue(Double.parseDouble(propsList.get(2).trim()));
            }
            if (propsList.size() > 3) {
               item.setRemark(propsList.get(3).trim());
            }
            iotVirtualItemList.add(item);
        }
        return iotVirtualItemList;
    }


    /**
     * 生成一个简单的 虚拟设备挂到空间下
     *
     * @param iotSpace
     */
    public void generateModelVirtualIotDev(IotSpace iotSpace) {
        IotDev virDev = new IotDev();
        virDev.setSn(UUIDUtils.generateRandomLetter() + UUIDUtils.generateUUID());  //编号
        virDev.setType(2);
        virDev.setScriptSwitch(1);
        IotDevType devType = new IotDevType();
        devType.setId(1L);
        virDev.setIotDevType(devType);
        virDev.setIotSpace(iotSpace);
        virDev.setScript("");
        virDev.setName("ModelName");
        iotDevRepo.saveAndFlush(virDev);
    }


    /**
     * 自动建立 制冷机房的虚拟设备数据
     *
     * @param iotSpace    虚拟设备
     * @param stationType 站房类型
     * @param overSee     监视系统类型 gas：气源系统 cold：冷却系统
     */
    @CacheEvict(value = "iotDev", allEntries = true)
    @Transactional
    public void autoGenerateCoolSysVirtualDevice(IotSpace iotSpace, String stationType, String overSee) {
        String queryParent = queryParent(iotSpace.getId());
        if (queryParent != null) {
            CacheUtils.guavaCacheFactory.put(SPACE_LEVEL_PREFIX + iotSpace.getId(), queryParent);
        }
        //自动生成设备属性
        autoGenerateDevicePropertys(stationType, overSee, iotSpace);
    }

    //自动生成空压站、制冷站监视系统一的设备属性
    public void autoGenerateDevicePropertys(String stationType, String overSee, IotSpace iotSpace) {
        IotDev virDev = new IotDev();
        virDev.setSn(UUIDUtils.generateRandomLetter() + UUIDUtils.generateUUID());  //编号
        virDev.setType(2);
        virDev.setScriptSwitch(1);
        IotDevType devType = new IotDevType();
        devType.setId(1L);
        virDev.setIotDevType(devType);
        virDev.setIotSpace(iotSpace);
        virDev.setPic("1999");
        virDev.setScript("");
        // 自动生成设备属性，创建属性数组
        String[] virStr = new String[8];
        String js = null;
        if (stationType.contains("空压")) {
            if (overSee.equals("gas")) {
                virDev.setName("空压机房气源系统");
                virStr = new String[]{"1#离心机状态", "2#离心机状态", "3#离心机状态", "4#离心机状态", "1#螺杆机状态", "2#螺杆机状态",
                        "3#螺杆机状态", "1#冷干机状态", "2#冷干机状态", "3#冷干机状态",
                        "4#冷干机状态", "5#冷干机状态", "1#吸干机状态", "2#吸干机状态", "1#储气罐状态", "2#储气罐状态",
                        "1#离心机出气控制阀状态", "2#离心机出气控制阀状态", "3#离心机出气控制阀状态", "4#离心机出气控制阀状态", "1#螺杆机出气控制阀状态",
                        "2#螺杆机出气控制阀状态", "1#冷干机进气控制阀状态", "2#冷干机进气控制阀状态", "3#冷干机进气控制阀状态", "4#冷干机进气控制阀状态",
                        "5#冷干机进气控制阀状态", "1#干燥机进气控制阀状态", "2#干燥机进气控制阀状态"};
                js = "10659.js";
            } else {
                virDev.setName("空压机房冷却系统");
                virStr = new String[]{"1#离心机状态", "2#离心机状态", "3#离心机状态", "4#离心机状态", "1#螺杆机状态", "2#螺杆机状态",
                        "3#螺杆机状态", "1#冷却塔状态", "2#冷却塔状态", "3#冷却塔状态",
                        "4#冷却塔状态", "1#干燥机状态", "2#干燥机状态", "1#冷干机状态", "2#冷干机状态", "3#冷干机状态",
                        "4#冷却泵状态", "1#离心机供水控制阀状态", "2#离心机供水控制阀状态", "3#离心机供水控制阀状态", "4#离心机供水控制阀状态",
                        "1#螺杆机供水控制阀状态", "2#螺杆机供水控制阀状态", "3#螺杆机供水控制阀状态", "1#干燥机供水控制阀状态", "2#干燥机供水控制阀状态",
                        "1#冷干机供水控制阀状态", "2#冷干机供水控制阀状态", "3#冷干机供水控制阀状态", "4#冷干机供水控制阀状态", "5#冷干机供水控制阀状态"};
                js = "10660.js";
            }
        }

        if (stationType.contains("制冷")) {
            virDev.setName("制冷机房系统");
            virStr = new String[]{"1#制冷主机状态", "2#制冷主机状态", "3#制冷主机状态", "4#制冷主机状态", "1#冷冻泵状态", "2#冷冻泵状态",
                    "3#冷冻泵状态", "4#冷冻泵状态", "1#冷却塔状态", "2#冷却塔状态", "3#冷却塔状态", "4#冷却塔状态", "1#冷却泵状态", "2#冷却泵状态", "3#冷却泵状态",
                    "4#冷却泵状态", "1#制冷主机冷冻水回水电动阀", "1#制冷主机冷却水回水电动阀", "2#制冷主机冷冻水回水电动阀", "2#制冷主机冷却水回水电动阀"};
            js = "10658.js";
        }
        List<IotVirtualItem> birs = new ArrayList<>();
        for (int i = 0; i < virStr.length; i++) {
            IotVirtualItem cu = new IotVirtualItem();
            cu.setSort(i);
            cu.setIsGet(1);
            cu.setIsLog(1);
            cu.setName(virStr[i]);
            cu.setPropertyType(100);
            cu.setType("开关量");
            birs.add(cu);
        }
        virDev.setVirtualItems(birs);
        InputStream stm = IotSpaceServiceImpl.class.getResourceAsStream("/scripts/codeUsedScript/" + js);
        if (stm != null) {
            try {
                virDev.setScript(new String(ByteStreams.toByteArray(stm)));
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        iotDevRepo.saveAndFlush(virDev);
    }

    /**
     * 制冷站房 - 工艺能效 - 顶部总量虚拟设备
     *
     * @param iotSpace
     * @param stationType 站房类型
     */
    @CacheEvict(value = "iotDev", allEntries = true)
    @Transactional
    public void autoGenerateCoolSysVirtualDevices(IotSpace iotSpace, String stationType) {
        String queryParent = queryParent(iotSpace.getId());
        if (queryParent != null) {
            CacheUtils.guavaCacheFactory.put(SPACE_LEVEL_PREFIX + iotSpace.getId(), queryParent);
        }
        IotDev virDev = new IotDev();
        virDev.setSn(UUIDUtils.generateRandomLetter() + UUIDUtils.generateUUID());   // 编号
        virDev.setType(2);       // 虚拟设备
        virDev.setScriptSwitch(1);
        virDev.setPic("1999");
        IotDevType devType = new IotDevType();
        devType.setId(1L);
        virDev.setIotDevType(devType);
        virDev.setIotSpace(iotSpace);
        //建立属性
        String[] virStr = new String[6];
        if (stationType.equals("空压站房")) {
            virDev.setName("空压总量统计");
            virStr = new String[]{"总气量", "总用水", "总耗电", "总电费", "单方用电", "单方电费"};
        }
        if (stationType.equals("制冷站房")) {
            virDev.setName("制冷总量统计");
            virStr = new String[]{"总冷量", "总用水", "总耗电", "总电费", "单方用电", "单方电费"};
        }
        List<IotVirtualItem> items = getIotVirtualItemList(virStr,iotSpace);
        virDev.setVirtualItems(items);
        virDev.setScript("");
        // 读取制冷机房的 js 脚本
        InputStream stm = IotSpaceServiceImpl.class.getResourceAsStream("/scripts/codeUsedScript/1909.js");
        if (stm != null) {
            try {
                virDev.setScript(new String(ByteStreams.toByteArray(stm)));
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        iotDevRepo.saveAndFlush(virDev);

    }


    /**
     * 属性数组转List集合
     *
     * @param virItems
     * @return
     */
    public List<IotVirtualItem> getIotVirtualItemList(String[] virItems,IotSpace iotSpace) {
        List<IotVirtualItem> items = new ArrayList<>();
        for (int i = 0; i < virItems.length; i++) {
            IotVirtualItem item = new IotVirtualItem();
            item.setSort(i);
            item.setIsGet(1);
            item.setIsLog(1);
            item.setName(virItems[i]);
            if ("总供冷".equals(virItems[i]) || "总用电".equals(virItems[i])) {
                String sql = "select dev.sn\n" +
                        "from iot_dev dev\n" +
                        "         left join iot_space i on dev.space_id = i.id\n" +
                        "where i.parent_id = (select parent_id from iot_space where id = "+iotSpace.getId()+")\n" +
                        "  and i.name = '总量栏'";
                String devSn = em.createNativeQuery(sql).getSingleResult().toString();
                if (devSn != null && "总供冷".equals(virItems[i])) {
                    item.setFormula(devSn + ".总冷量");
                }
                if (devSn != null && "总用电".equals(virItems[i])) {
                    item.setFormula(devSn + ".总耗电");
                }
            }
            item.setPropertyType(100);
            item.setType("累积量");
            items.add(item);
        }
        return items;
    }


    /**
     * 制冷站房 - 工艺能效 - 一区设备
     *
     * @param iotSpace
     * @param stationType 站房类型
     * @param region      区域 1-一区 2-二区
     */
    @CacheEvict(value = "iotDev", allEntries = true)
    @Transactional
    public void autoGenerateCoolSysVirtualDevicesZone(IotSpace iotSpace, String stationType, int region) {
        String queryParent = queryParent(iotSpace.getId());
        if (queryParent != null) {
            CacheUtils.guavaCacheFactory.put(SPACE_LEVEL_PREFIX + iotSpace.getId(), queryParent);
        }
        IotDev virDev = new IotDev();
        virDev.setSn(UUIDUtils.generateRandomLetter() + UUIDUtils.generateUUID());
        virDev.setType(2);
        virDev.setScriptSwitch(1);
        virDev.setPic("1999");
        IotDevType devType = new IotDevType();
        devType.setId(1L);
        virDev.setIotDevType(devType);
        //建立属性
        String[] virStr = new String[2];
        if (stationType.equals("空压站房")) {
            if (region == 1) {
                virDev.setName("站房用气趋势图&饼图");
                virStr[0] = "总用气";
            }
            if (region == 2) {
                virDev.setName("站房用电趋势图&饼图");
                virStr[0] = "总用电";
            }
        }
        if (stationType.equals("制冷站房")) {
            if (region == 1) {
                virDev.setName("站房用冷趋势图&饼图");
                virStr[0] = "总供冷";
            }
            if (region == 2) {
                virDev.setName("站房用电趋势图&饼图");
                virStr[0] = "总用电";
            }
        }
        virStr[1] = "总价格";
        virDev.setIotSpace(iotSpace);
        List<IotVirtualItem> items = getIotVirtualItemList(virStr, iotSpace);
        virDev.setVirtualItems(items);
        virDev.setScript("");
        // 读取制冷机房的 js 脚本
        String jsPath = null;
        if (region == 1) {
            jsPath = "/scripts/codeUsedScript/1995.js";
        }
        if (region == 2) {
            jsPath = "/scripts/codeUsedScript/1996.js";
        }
        InputStream stm = IotSpaceServiceImpl.class.getResourceAsStream(jsPath);
        if (stm != null) {
            try {
                virDev.setScript(new String(ByteStreams.toByteArray(stm)));
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        iotDevRepo.saveAndFlush(virDev);
    }


    /**
     * 插入，批量保存
     *
     * @param list 实体集合
     * @return List<T>
     */
    @Override
    public List<IotSpace> insertObjInBatch(List<IotSpace> list) {
        return null;
    }

    /**
     * 更新
     *
     * @param device 跟新的实体
     * @return T
     */
    @Transactional(rollbackOn = Exception.class)
    @Override
    public IotSpace update(IotSpace device) {
        IotSpace dbResult = spaceRepo.saveAndFlush(device);
//		CacheUtils.guavaCacheFactory.put(CommonConstants.SPACE_LEVEL_PREFIX+dbResult.getId(),queryParent(dbResult.getId()));
        return dbResult;
    }

    /**
     * 删除--批量删除
     *
     * @param ids 批量删除id
     * @return int 影响数
     */
    @Transactional(rollbackOn = Exception.class)
    @Override
    public int delete(Long[] ids) {

        // 初始化数据
        List<Long> oriData = Arrays.asList(ids);

        // 获取与空间相关的设备
        for (int i = 0; i < ids.length; i++) {
            Long Item = ids[i];
            // 获取 该节点下的子级空间id--- 包含自己
            String sql = "select countupSpaceSubsets (" + Item + ")";
            String singleResult = em.createNativeQuery(sql).getSingleResult().toString();
            List<Long> sonIds = Splitter.on(",").splitToList(singleResult).stream().filter(str -> !str.equals("")).map(si -> Long.parseLong(si)).collect(Collectors.toList());

            // 合并去重 空间id
            oriData = Stream.concat(oriData.stream(), sonIds.stream()).distinct().map(son -> Long.parseLong(son.toString())).collect(Collectors.toList());

            sonIds.forEach(sid -> {
                // 先设置 设备的空间 为空
                IotSpace iotSpace = new IotSpace();
                iotSpace.setId(sid);
                // 删除一些缓存
                CacheUtils.guavaCacheFactory.invalidate(SPACE_LEVEL_PREFIX + sid);
                List<IotDev> allByIotSpace = iotDevRepo.getAllByIotSpace(iotSpace);
                if (allByIotSpace.size() > 0) {
                    List<Long> toBeDel = allByIotSpace.stream().map(item -> item.getId()).collect(Collectors.toList());
                    iotDevRepo.emptySpaceData(toBeDel);
                }
            });

        }
        return spaceRepo.deleteByIdIn(oriData.stream().toArray(Long[]::new));
    }

    /**
     * 获取列表数据---使用 com.mach.platform.utils.springdata  下的DynamicSpecifications 的
     * 写法进行分页查询
     *
     * @param pageable 分页参数
     * @param params   其他参数
     * @return Page<T>
     */
    @Override
    public Page<IotSpace> list(Pageable pageable, Map params) {

        Specification specification = DynamicSpecifications.bySearchFilter(SearchFilter.parse(params).values(), IotSpace.class);

        return spaceRepo.findAll(specification, pageable);
    }

    /**
     * 获取单体 数据
     *
     * @param id 获取详情的id
     * @return T
     */
    @Override
    public IotSpace info(Long id) {
        return spaceRepo.getById(id);
    }

    /**
     * 递归
     * 获取 空间的 级联 选择数据结构
     *
     * @return
     */
    public List<Map> spaceTreeDatas() {

        List<IotSpace> dataStore = spaceRepo.findAll();

        IotSpace topestSpace = spaceRepo.loadTopSpace();

        if (topestSpace == null) {
            return Collections.EMPTY_LIST;
        }

        List<Map> result = Lists.newArrayList();
        result.add(makeMap(topestSpace, dataStore));

        return result;
    }

    /**
     * 递归数据执行体
     *
     * @param curId
     * @param store
     * @return
     */
    public List<Map> recursion(Long curId, List<IotSpace> store) {

        List<Map> children = Lists.newArrayList();

        for (int i = 0; i < store.size(); i++) {
            IotSpace curItem = store.get(i);
            if (curId.equals(curItem.getParentId())) {
                children.add(makeMap(curItem, store));
            }
        }
        //排序 按照 sort来排序
        if (children.size() > 0) {
            children.sort((o1, o2) -> {
                if (o1.get("sort") == null) {
                    return 1;
                }

                if (o2.get("sort") == null) {
                    return -1;
                }

                return Integer.parseInt(o1.get("sort").toString()) - Integer.parseInt(o2.get("sort").toString());
            });

        }

        return children;
    }

    /**
     * 生成 字典数据
     *
     * @param iotSpace
     * @param store
     * @return
     */
    public Map makeMap(IotSpace iotSpace, List<IotSpace> store) {

        Map map = Maps.newHashMap();
        map.put("label", iotSpace.getName());
        map.put("value", iotSpace.getId());
        map.put("sort", iotSpace.getSort());
//		map.put("layoutPic", iotSpace.getLayoutPic()==null?"":iotSpace.getLayoutPic());
        List<Map> mapList = recursion(iotSpace.getId(), store);
        if (mapList.size() > 0) {
            map.put("children", mapList);
        }
        return map;
    }


    public void configureSpaceLevelDataTask() {

        List<IotSpace> all = spaceRepo.findAll();
        if (all.size() > 0) {
            all.forEach(item -> {
                Long curId = item.getId();
                String levelCheck = queryParent(curId);
                if (levelCheck != null) {
                    CacheUtils.guavaCacheFactory.put(SPACE_LEVEL_PREFIX + curId, levelCheck);
                }
            });

        }
    }


    /**
     * 根据架构id获取架构名字全称(用/连接)
     *
     * @param id 架构id
     * @return
     */
    public String getEnergyFullName(Long id) {
        String sql = "select GROUP_CONCAT(T2. NAME ORDER BY T1.lvl DESC separator '/') as levelEnergy \n" +
                "FROM ( \n" +
                "    SELECT \n" +
                "        @r AS _id, \n" +
                "        (SELECT @r \\:= pid FROM energy_struc WHERE id = _id) AS pid, \n" +
                "        @l \\:= @l + 1 AS lvl \n" +
                "    FROM \n" +
                "        (SELECT  @l \\:= 0) vars, \n" +
                "        energy_struc h \n" +
                "    WHERE @r <> 0) T1 \n" +
                "JOIN energy_struc T2 \n" +
                "ON T1._id = T2.id \n" +
                " where @r \\:=" + id;
        Query query = em.createNativeQuery(sql);
        query.unwrap(SQLQuery.class).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
        List<Map<String, String>> result = query.getResultList();
        if (result == null || result.size() == 0) {
            return null;
        }
        return result.get(0).get("levelEnergy") == null ? null : result.get(0).get("levelEnergy");
    }


    /**
     * 根据空间id获取空间名字全称(用>连接)
     *
     * @param sid 空间id
     * @return
     */
    public String queryParent(Long sid) {
        /*String sql1 = "select GROUP_CONCAT(T2. NAME ORDER BY T1.lvl DESC separator '>') as levelSpace \n" +
                "FROM ( \n" +
                "    SELECT \n" +
                "        @r AS _id, \n" +
                "        (SELECT @r \\:= parent_id FROM iot_space WHERE id = _id) AS parent_id, \n" +
                "        @l \\:= @l + 1 AS lvl \n" +
                "    FROM \n" +
                "        (SELECT  @l \\:= 0) vars, \n" +
                "        iot_space h \n" +
                "    WHERE @r <> 0) T1 \n" +
                "JOIN iot_space T2 \n" +
                "ON T1._id = T2.id \n" +
                " where @r \\:=" + sid;*/
//        Query query = em.createNativeQuery(sql);
//        query.unwrap(SQLQuery.class).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
//        List<Map<String, String>> result = query.getResultList();
//        if (result == null || result.size() == 0) {
//            return null;
//        }
//        return result.get(0).get("levelSpace") == null ? null : result.get(0).get("levelSpace");

        SqlHelper sqlHelper = SqlHelper.getBySource(dataSource);
        String sql = "SELECT GROUP_CONCAT(T2.NAME ORDER BY T1.lvl DESC separator '>') as levelSpace\n" +
                "FROM ( \n" +
                "    SELECT \n" +
                "        @r AS _id, \n" +
                "        (SELECT @r :=parent_id FROM iot_space WHERE id = _id) AS parent_id, \n" +
                "        @l :=@l + 1 AS lvl \n" +
                "    FROM \n" +
                "        (SELECT @r :="+ sid +", @l :=0) vars,\n" +
                "        iot_space h \n" +
                "    WHERE @r <> 0) T1 \n" +
                "JOIN iot_space T2 \n" +
                "ON T1._id = T2.id \n" +
                "ORDER BY T1.lvl DESC";
        try {
            Map resultMap = sqlHelper.queryOne(sql);
            Optional<Map> optionalMap = Optional.ofNullable(resultMap);
            return optionalMap.map(map -> map.get("levelSpace")).map(Object::toString).orElse(null);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 空间----加载站房的选项数据
     *
     * @return
     */
    public List<Map> loadStationSelectionDatas(Integer spaceId, Integer type) {
        List<Map> dbResult = spaceRepo.loadStationSelectionDatas(spaceId, type);
        if (dbResult == null) {
            return Collections.EMPTY_LIST;
        }
        return dbResult;
    }

    /**
     * 加载顶部栏的菜单
     *
     * @param spaceId
     * @param type
     * @return
     */
    public List<Map> loadStationSelectionDatass(Integer spaceId, Integer type) {

        //查询空间节点的子节点
        List<Map> sonSpaces = spaceRepo.loadStationSelectionDatas(spaceId, type);
		/*
		在写方法的时候可能结果集不存在，需要返回null,在调用这个方法的地方就要做一个null判断,很繁琐，容易出问题，
		这个时候就可以使用emptyList或EMPTY_LIST。但是也会有同学说我new ArrayList不就可以了，这样是可以，
		但是每次我们new 一个集合对象的时候都会有一个初始化空间，占用内存资源，积少成多会浪费很多的资源，
		Collections中的空集合对象是一个静态常量，在内存中只存在一份，所以能够节省内存资源。
		 */
        if (sonSpaces.size() == 0) {
            return Collections.EMPTY_LIST;
        }
        Map targetMap = sonSpaces.get(0);
        //  Pid表示设备空间id
        List<IotSpace> stationsDbResult = spaceRepo.loadStationsObjsByPid(Long.parseLong(targetMap.get("value").toString()));


        return stationsDbResult.stream().sorted(Comparator.comparing(IotSpace::getSort, Comparator.nullsLast(Integer::compareTo))).map(hel -> {

            Map boj = new HashMap();
            boj.put("value", hel.getId());
            boj.put("label", hel.getName());
            return boj;
        }).collect(Collectors.toList());

    }

}
